import logging
import argparse
from dingtalk_stream import AckMessage
import dingtalk_stream
from http import HTTPStatus
from loguru import logger
from dashscope import Generation
from typing import Callable
import requests
import cfg  # 导入配置文件

import os
import dashscope

# 设置DashScope API Key
#os.environ["DASHSCOPE_API_KEY"] = "sk-c2f4e73246e14ebb9f98890fec3cc3e9"
import dashscope

dashscope.api_key = "sk-c2f4e73246e14ebb9f98890fec3cc3e9"  # 将 "your-api-key" 替换为您的实际 API Key

def define_options():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--client_id",
        dest="client_id",
        required=True,
        help="app_key or suite_key from https://open-dev.digntalk.com",
    )
    parser.add_argument(
        "--client_secret",
        dest="client_secret",
        required=True,
        help="app_secret or suite_secret from https://open-dev.digntalk.com",
    )
    options = parser.parse_args()
    return options


def call_with_stream(request_content: str, callback: Callable[[str], None], user_id: str) -> str:
    # post请求http://127.0.0.1:8765/get_info,
    # 参数为{"user_id": 用户ID, "question": request_content}
    # 获取返回结果中的message字段作为外部信息
    request_result = requests.post("http://127.0.0.1:8765/get_info",
                                  json={"user_id": user_id, "question": request_content})
    request_result = request_result.json()
    external_info = request_result["message"]
    request_content = f"<已知信息>{external_info}</已知信息> <问题>{request_content}</问题>"

    messages = [{"role": "system", "content": "你叫盯小龙，是一个由龙垣科技人工智能研发部打造的人事助手，你的任务是有逻辑的对问题进行分析和解答，不应该有任何情感色彩和偏见。回答不要过长，不要说废话"}]
    messages += [{"role": "user", "content": request_content}]

    responses = Generation.call(
        Generation.Models.qwen_max,
        messages=messages,
        result_format="message",  # set the result to be "message" format.
        stream=True,  # set stream output.
        incremental_output=True,  # get streaming output incrementally.
    )
    full_content = ""  # with incrementally we need to merge output.
    length = 0
    for response in responses:
        if response.status_code == HTTPStatus.OK:
            full_content += response.output.choices[0]["message"]["content"]
            full_content_length = len(full_content)
            if full_content_length - length > 2000:
                callback(full_content)
                logger.info(f"调用流式更新接口更新内容：current_length={length}, next_length={full_content_length}")
                length = full_content_length
        else:
            raise Exception(
                f"Request id: {response.request_id}, Status code: {response.status_code}, error code: {response.code}, error message: {response.message}"
            )
    logger.info(f"Request Content: {request_content}\nFull response: {full_content}\nFull response length: {len(full_content)}")
    return full_content


class CardBotHandler(dingtalk_stream.ChatbotHandler):
    def __init__(self, logger: logging.Logger = logger):
        super(dingtalk_stream.ChatbotHandler, self).__init__()
        if logger:
            self.logger = logger

    async def process(self, callback: dingtalk_stream.CallbackMessage):
        incoming_message = dingtalk_stream.ChatbotMessage.from_dict(callback.data)
        sender = incoming_message.sender_nick
        self.logger.info(f"收到消息：{incoming_message}")

        if incoming_message.message_type != "text":
            self.reply_text("盯小龙暂时只支持文字喔~", incoming_message)
            return AckMessage.STATUS_OK, "OK"

        card_template_id = "c2ecc476-cede-4631-890c-4b2fd13599b4.schema"
        content_key = "content"
        card_data = {content_key: ""}
        card_instance = dingtalk_stream.AICardReplier(
            self.dingtalk_client, incoming_message
        )
        # 先投放卡片
        card_instance_id = card_instance.create_and_send_card(
            card_template_id, card_data, callback_type="STREAM"
        )
        # 再流式更新卡片
        try:
            full_content_value = call_with_stream(
                incoming_message.text.content,
                lambda content_value: card_instance.streaming(
                    card_instance_id,
                    content_key=content_key,
                    content_value=content_value,
                    append=False,
                    finished=False,
                    failed=False,
                ),
                sender,
            )
            card_instance.streaming(
                card_instance_id,
                content_key=content_key,
                content_value=full_content_value,
                append=False,
                finished=True,
                failed=False,
            )
        except Exception as e:
            self.logger.exception(e)
            card_instance.streaming(
                card_instance_id,
                content_key=content_key,
                content_value="",
                append=False,
                finished=False,
                failed=True,
            )

        return AckMessage.STATUS_OK, "OK"


def main():
    client_id = cfg.CLIENT_ID  # 从配置文件中获取 client_id
    client_secret = cfg.CLIENT_SECRET  # 从配置文件中获取 client_secret

    credential = dingtalk_stream.Credential(client_id, client_secret)
    client = dingtalk_stream.DingTalkStreamClient(credential)
    client.register_callback_handler(
        dingtalk_stream.ChatbotMessage.TOPIC, CardBotHandler()
    )
    client.start_forever()


if __name__ == "__main__":
    main()
